package com.storm.container
{
	import com.storm.events.ItemEvent;
	
	import flash.display.DisplayObjectContainer;
	import flash.events.MouseEvent;
	
	import mx.containers.Canvas;
	import mx.core.ClassFactory;
	import mx.core.Container;
	import mx.core.UIComponent;
	
	public class BaseContainer extends Canvas {
		public function BaseContainer() {
			super();
		}
		
		private var _itemSelectEnabled:Boolean = true;
		public function get itemSelectEnabled():Boolean {
			return this._itemSelectEnabled;
		}
		public function set itemSelectEnabled(value:Boolean):void {
			this._itemSelectEnabled = value;
		}
		
		private var _itemClass:Class;
		public function get itemClass():Class {
			return this._itemClass;
		}
		public function set itemClass(value:Class):void {
			if (this._itemClass == value) return;
			this._itemClass = value;
			this._itemFactory = new ClassFactory(value);
		}
		
		private var _itemFactory:ClassFactory;
		
		private var _itemCached:Boolean = false;
		public function get itemCached():Boolean {
			return this._itemCached;
		}
		public function set itemCached(value:Boolean):void {
			this._itemCached = value;
		}
		
		protected function initializeItem(item:IBaseItem):void {
			if (this._itemSelectEnabled) {
				item.addEventListener(MouseEvent.MOUSE_DOWN, itemMouseDownHandler);
			}
			this.addChild(item);
		}
		
		protected function uninitializeItem(item:IBaseItem):void {
			if (this._itemSelectEnabled) {
				item.removeEventListener(MouseEvent.MOUSE_DOWN, itemMouseDownHandler);
			}
			this.removeChild(item);
		}
		
		public function clearItems():void {
			for each (var item:IBaseItem in this._items) {
				this.uninitializeItem(item);
			}
			this._backupItems = [];
			this._items = [];
		}
		
		protected function rebuildItems(datas:Array):void {
			this.clearItems();
			for each (var data:Object in datas) {
				var item:IBaseItem = this._itemFactory.newInstance();
				item.data = data;
				this.initializeItem(item);
				this._items.push(item);
			}
		}
		
		protected function getItemAt(index:int):IBaseItem {
			if (index == this._backupItems.length) {
				var item:IBaseItem = this._itemFactory.newInstance()*;
				this._backupItems.push(item);
				return item;
			} else {
				return this._backupItems[index];
			}
		}
		
		protected function resetItems(datas:Array):void {
			var i:int;
			var item:IBaseItem;
			for (i = datas.length; i < this._items.length; i++) {
				item = this._items[i];
				this.uninitializeItem(item);
				item.data = null;
			}
			this._items.splice(datas.length);
			for (i = 0; i < datas.length; i++) {
				item = this.getItemAt(i);
				item.data = datas(i);
				if (i >= this._items.length) {
					this.initializeItem(item);
					this._items.push(item);
				}
			}
		}
		
		private function itemMouseDownHandler(event:MouseEvent):void {
			this.selectedItem = event.currentTarget as IBaseItem;
		}
		
		private var _selectedItem:IBaseItem;
		public function get selectedItem():IBaseItem {
			return this._selectedItem;
		}
		public function set selectedItem(value:IBaseItem):void {
			if (this._selectedItem == value) return;
			if (this._selectedItem) {
				this._selectedItem.selected = false;
			}
			this._selectedItem = value;
			if (value) {
				value.selected = true;
			}
			this.selectedIndex = this._items.indexOf(value);
//			if (value) {
				this.dispatchEvent(new ItemEvent(ItemEvent.ITEM_SELECTED, value));
//			}
		}
		
		private var _selectedIndex:int = -1;
		public function get selectedIndex():int {
			return this._selectedIndex;
		}
		public function set selectedIndex(value:int):void {
			if (this._selectedIndex == value) return;
			this._selectedIndex = value;
			if (value == -1 || value >= this._items.length) {
				this.selectedItem = null;
			} else {
				this.selectedItem = this._items[value];
			}
		}
		
		private var _backupItems:Array;
		
		private var _items:Array;
		
		private var _datas:Array;
		public function get datas():Array {
			return this._datas;
		}
		public function set datas(value:Array):void {
			this._datas = value;
			
			if (!this._itemCached) {
				this.rebuildItems(datas);
			} else {
				this.resetItems(datas);
			}
			
			this.layoutItems();
		}
		
		protected function layoutItems():void {
			
		}
		
		public function foreachItem(handler:Function, backupItemsIncluded:Boolean = true):void {
			if (handler === null) return;
			var items:Array = backupItemsIncluded ? this._backupItems : this._items;
			for each (var item:IBaseItem in items) {
				handler(item);
			}
		}
	}
}